package com.biu.billiards.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.biu.billiards.model.bo.DeviceBO;
import com.biu.billiards.model.entity.Device;
import com.biu.billiards.mapper.DeviceMapper;
import com.biu.billiards.model.entity.Hardware;
import com.biu.billiards.model.vo.device.AddDeviceVo;
import com.biu.billiards.model.vo.device.GetDeviceVo;
import com.biu.billiards.model.vo.device.UpdateDeviceVO;
import com.biu.billiards.model.vo.mqtt.OpenDeviceVo;
import com.biu.billiards.mqqts.MqttService;
import com.biu.billiards.service.IBilliardsService;
import com.biu.billiards.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.biu.billiards.service.IHardwareService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xue
 * @since 2023-10-25
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {

    @Resource
    private IHardwareService hardwareService;

    @Autowired
    private MqttService mqttService;

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private IDeviceService deviceService;

    @Resource
    private IBilliardsService billiardsService;

//    @Autowired
//    private MqttMessageSender mqttMessageSender;


    @Override
    public List<Device> getTaskDeviceList(Boolean open,Integer shopId) {

        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopId);
        if (open){
            queryWrapper.eq("start_time",LocalDateTime.now().getHour());
        }else {
            queryWrapper.eq("end_time",LocalDateTime.now().getHour());
        }


        System.out.println("getTaskDeviceList");
        System.out.println(LocalDateTime.now().getHour());


        return deviceMapper.selectList(queryWrapper);

    }

    @Override
    public List<Device> getRuleDeviceList(Boolean open,Integer shopId) {

        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopId);

        if (open){
            queryWrapper.eq("before_status",1);
        }else {
            queryWrapper.eq("after_status",1);
        }


        return deviceMapper.selectList(queryWrapper);


    }

    @Override
    public List<Device> getDeviceList() {
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();


        return deviceMapper.selectList(queryWrapper);
    }


    @Override
    public void taskOpen(Boolean open,Integer shopId) {

        List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();

        List<Device> list = getTaskDeviceList(open,shopId);


        List<String> uniqueHardwareIds = new ArrayList<>();

        for (Device device:list){
            OpenDeviceVo openDeviceVo = new OpenDeviceVo();
            openDeviceVo.setNumber(device.getDeviceNumber());
            openDeviceVo.setDeviceId(device.getDeviceId());
            openDeviceVo.setOpen(open?1:0);
            openDeviceVo.setHardwareId(device.getHardwareId());

            // 检查 uniqueHardwareIds 是否已经包含当前的 hardwareId
            if (!uniqueHardwareIds.contains(device.getHardwareId())) {
                // 如果不包含，则将其添加到 uniqueHardwareIds 列表中
                uniqueHardwareIds.add(device.getHardwareId());
            }

            openDeviceVoList.add(openDeviceVo);
        }



        if (openDeviceVoList.size()!=0){

            for (String hardwareId : uniqueHardwareIds) {

                List<OpenDeviceVo> newOpenDeviceVoList = new ArrayList<>();
                for (OpenDeviceVo openDeviceVo:openDeviceVoList){
                    if (hardwareId.equals(openDeviceVo.getHardwareId())){
                        newOpenDeviceVoList.add(openDeviceVo);
                    }
                }
                openDevices(newOpenDeviceVoList,hardwareId);

            }

         //   openDevices(openDeviceVoList,shopId);
        }

    }

    @Override
    public void autoOpenVrv(Integer shopIp) {

        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopIp);
        queryWrapper.ne("control","");

        List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();

        List<Device> list = deviceMapper.selectList(queryWrapper);
        List<Device> tarList = new ArrayList<>();

        for (Device device:list){
            String[] str = device.getControl().split(",");
            if (str.length>0){
                if (billiardsService.getBilliardsStatusOpen(shopIp,str)){
                    tarList.add(device);
                  //  break;
                }
            }
        }

        System.out.println("tarListtarListopen");
        System.out.println(tarList);

//        [Device(deviceId=16, status=0, deviceNumber=3, deviceName=空调1,
//                shopId=5, startTime=null, endTime=null, beforeStatus=0, afterStatus=0,
//                hardwareId=CORX000010A5, control=12,13,14)]

        List<String> uniqueHardwareIds = new ArrayList<>();

        for (Device device:tarList){
            OpenDeviceVo openDeviceVo = new OpenDeviceVo();
            openDeviceVo.setNumber(device.getDeviceNumber());
            openDeviceVo.setDeviceId(device.getDeviceId());
            openDeviceVo.setOpen(1);
            openDeviceVo.setHardwareId(device.getHardwareId());

            // 检查 uniqueHardwareIds 是否已经包含当前的 hardwareId
            if (!uniqueHardwareIds.contains(device.getHardwareId())) {
                // 如果不包含，则将其添加到 uniqueHardwareIds 列表中
                uniqueHardwareIds.add(device.getHardwareId());
            }

            openDeviceVoList.add(openDeviceVo);
        }

        System.out.println("openDeviceVoListopenDeviceVoList");
        System.out.println(openDeviceVoList);

        System.out.println("uniqueHardwareIdsuniqueHardwareIds");
        System.out.println(uniqueHardwareIds);


        if (openDeviceVoList.size()!=0){
            for (String hardwareId : uniqueHardwareIds) {

                List<OpenDeviceVo> newOpenDeviceVoList = new ArrayList<>();
                for (OpenDeviceVo openDeviceVo:openDeviceVoList){

                    if (hardwareId.equals(openDeviceVo.getHardwareId())){
                        newOpenDeviceVoList.add(openDeviceVo);
                    }
                }

                openDevices(newOpenDeviceVoList,hardwareId);

            }
        }

        //openDevices(openDeviceVoList,shopIp);


    }

    @Override
    public void autoCloseVrv(Integer shopIp) {

        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopIp);
        queryWrapper.ne("control","");

        List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();

        List<Device> list = deviceMapper.selectList(queryWrapper);
        List<Device> tarList = new ArrayList<>();

        for (Device device:list){
            String[] str = device.getControl().split(",");
            if (str.length>0){
                if (billiardsService.getBilliardsStatusClose(shopIp,str)){
                    tarList.add(device);
                 //   break;
                }
            }
        }
        System.out.println("tarListtarListclse");
        System.out.println(tarList);

//        [Device(deviceId=16, status=1, deviceNumber=3, deviceName=空调1,
//                shopId=5, startTime=null, endTime=null, beforeStatus=0, afterStatus=0, hardwareId=CORX000010A5, control=12,13,14)]

        List<String> uniqueHardwareIds = new ArrayList<>();

        for (Device device:tarList){
            OpenDeviceVo openDeviceVo = new OpenDeviceVo();
            openDeviceVo.setNumber(device.getDeviceNumber());
            openDeviceVo.setDeviceId(device.getDeviceId());
            openDeviceVo.setOpen(0);
            openDeviceVo.setHardwareId(device.getHardwareId());

            // 检查 uniqueHardwareIds 是否已经包含当前的 hardwareId
            if (!uniqueHardwareIds.contains(device.getHardwareId())) {
                // 如果不包含，则将其添加到 uniqueHardwareIds 列表中
                uniqueHardwareIds.add(device.getHardwareId());
            }

            openDeviceVoList.add(openDeviceVo);
        }

        System.out.println("openDeviceVoListopenDeviceVoList");
        System.out.println(openDeviceVoList);

        System.out.println("uniqueHardwareIdsuniqueHardwareIds");
        System.out.println(uniqueHardwareIds);


        if (openDeviceVoList.size()!=0){
            for (String hardwareId : uniqueHardwareIds) {

                List<OpenDeviceVo> newOpenDeviceVoList = new ArrayList<>();
                for (OpenDeviceVo openDeviceVo:openDeviceVoList){

                    if (hardwareId.equals(openDeviceVo.getHardwareId())){
                        newOpenDeviceVoList.add(openDeviceVo);
                    }
                }

                openDevices(newOpenDeviceVoList,hardwareId);

            }
        }

    }


    @Override
    public Boolean openDevices(List<OpenDeviceVo> openDeviceVoList,String deviceId) {


        System.out.println("openDevicesopenDevices");

        System.out.println(openDeviceVoList);
        System.out.println(deviceId);

        String msg = "{";

        for (OpenDeviceVo openDeviceVo:openDeviceVoList){

            UpdateDeviceVO updateDeviceVO = new UpdateDeviceVO();
            updateDeviceVO.setDeviceId(openDeviceVo.getDeviceId());

            String no = String.format("%02d", openDeviceVo.getNumber());

            if (openDeviceVo.getOpen()==1) {

                msg=msg+"\"A"+no+"\":110000,";

                updateDeviceVO.setStatus(1);

            }else {

                msg=msg+"\"A"+no+"\":100000,";

                updateDeviceVO.setStatus(0);
            }

            deviceService.updateDevice(updateDeviceVO);

        }
        msg=msg+"\"res\":\"5123\"}";
        //{"A09":110000,"res":"5123"}

        System.out.println("dsadasdasddsadasdasd");



     //  Hardware hardware = hardwareService.getSubHardware(shopId);

       String sup =  hardwareService.getSubHardware(deviceId);

        System.out.println("supsup");
        System.out.println(sup);

       if (sup!=null){
           mqttService.publish(msg,sup);
       }

       //mqttMessageSender.send("/corx/sub/CORX00001000",msg);

        return true;
    }




    private void openVrvBefore(List<Device> list,Integer shopId){

        System.out.println("openVrvBefore");
        System.out.println(list);

        //有人玩的时候 打开设备
    //    List<Device> tar = new ArrayList<>();
        List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();
        List<String> uniqueHardwareIds = new ArrayList<>();
        for (Device device:list){

            //当前状态是关闭 需要关闭的设备
            if (device.getStatus()==0 && device.getBeforeStatus()==1){

                OpenDeviceVo openDeviceVo = new OpenDeviceVo();
                openDeviceVo.setOpen(1);
                openDeviceVo.setDeviceId(device.getDeviceId());
                openDeviceVo.setNumber(device.getDeviceNumber());
                openDeviceVo.setHardwareId(device.getHardwareId());
                // 检查 uniqueHardwareIds 是否已经包含当前的 hardwareId
                if (!uniqueHardwareIds.contains(device.getHardwareId())) {
                    // 如果不包含，则将其添加到 uniqueHardwareIds 列表中
                    uniqueHardwareIds.add(device.getHardwareId());
                }
                openDeviceVoList.add(openDeviceVo);

                //当前状态是打开 需要打开的设备
            }

        }


        if (openDeviceVoList.size()!=0){
            for (String hardwareId : uniqueHardwareIds) {
                List<OpenDeviceVo> newOpenDeviceVoList = new ArrayList<>();
                for (OpenDeviceVo openDeviceVo:openDeviceVoList){
                    if (hardwareId.equals(openDeviceVo.getHardwareId())){
                        newOpenDeviceVoList.add(openDeviceVo);
                    }
                }
                openDevices(newOpenDeviceVoList,hardwareId);

            }
        }


        System.out.println("总共的");
        System.out.println(list);
        System.out.println("要开的的的的的的的的的的");
        System.out.println(openDeviceVoList);

    }


    private void openVrvAfter(List<Device> list,Integer shopId){

        System.out.println("openVrvAfter");
        System.out.println(list);

        //没有玩的时候 打开设备
        //    List<Device> tar = new ArrayList<>();
        List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();
        List<String> uniqueHardwareIds = new ArrayList<>();

        for (Device device:list){

            //当前状态是关闭 需要关闭的设备
            if (device.getStatus()==1 && device.getAfterStatus()==1){

                OpenDeviceVo openDeviceVo = new OpenDeviceVo();
                openDeviceVo.setOpen(0);
                openDeviceVo.setDeviceId(device.getDeviceId());
                openDeviceVo.setNumber(device.getDeviceNumber());
                openDeviceVo.setHardwareId(device.getHardwareId());

                // 检查 uniqueHardwareIds 是否已经包含当前的 hardwareId
                if (!uniqueHardwareIds.contains(device.getHardwareId())) {
                    // 如果不包含，则将其添加到 uniqueHardwareIds 列表中
                    uniqueHardwareIds.add(device.getHardwareId());
                }
                openDeviceVoList.add(openDeviceVo);

                //当前状态是打开 需要打开的设备
            }

        }

        if (openDeviceVoList.size()!=0){
            for (String hardwareId : uniqueHardwareIds) {
                List<OpenDeviceVo> newOpenDeviceVoList = new ArrayList<>();
                for (OpenDeviceVo openDeviceVo:openDeviceVoList){
                    if (hardwareId.equals(openDeviceVo.getHardwareId())){
                        newOpenDeviceVoList.add(openDeviceVo);
                    }
                }
                openDevices(newOpenDeviceVoList,hardwareId);
            }
        }

//        if (openDeviceVoList.size()!=0){
//
//            openDevices(openDeviceVoList,shopId);
//
//        }

    }

    @Override
    public void openVrv(Boolean open,Integer shopId) {


        System.out.println("openVrvopenVrvopenVrvopenVrv");

      //  List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();

        List<Device> list = getRuleDeviceList(open,shopId);

//        System.out.println("openVrvaasdasdasd");
//        System.out.println("openVrv");
//        System.out.println(open);
//        System.out.println("要"+open+"的设备");
//        System.out.println(list);

        if (open){

           // System.out.println("打开了");
            System.out.println("有人玩");
            System.out.println("有人玩有人玩有人玩有人玩有人玩有人玩");

            openVrvBefore(list,shopId);

        }else {

           // System.out.println("关闭了");
            System.out.println("没人玩1111");
            openVrvAfter(list,shopId);

        }

    }

    @Override
    public void openFan(Integer open) {


        List<OpenDeviceVo> openDeviceVoList = new ArrayList<>();

        OpenDeviceVo openDeviceVo1 = new OpenDeviceVo();
        OpenDeviceVo openDeviceVo2 = new OpenDeviceVo();


        //风扇
        openDeviceVo1.setDeviceId(5);
        openDeviceVo1.setNumber(10);
        openDeviceVo1.setOpen(open);

        //风扇
        openDeviceVo2.setDeviceId(6);
        openDeviceVo2.setNumber(11);
        openDeviceVo2.setOpen(open);


        openDeviceVoList.add(openDeviceVo1);
        openDeviceVoList.add(openDeviceVo2);


      //  openDevices(openDeviceVoList);

//        for (OpenDeviceVo openDeviceVo:openDeviceVoList){
//
//            openDeviceVo.setOpen(openDeviceVo.getOpen());
//            openDeviceVo.setNumber(openDeviceVo.getNumber());
//            openDeviceVo.setDeviceId(openDeviceVo.getDeviceId());
//            billiardsService.openDevice(openDeviceVo);
//
//        }

    }

    @Override
    public void openDoor(OpenDeviceVo openDeviceVo){


        UpdateDeviceVO updateDeviceVO = new UpdateDeviceVO();

        updateDeviceVO.setDeviceId(openDeviceVo.getDeviceId());


        //  发送mqtt
        String msg;
        String no = String.format("%02d", openDeviceVo.getNumber());

        if (openDeviceVo.getOpen()==1) {
            msg = "{\"A"+no+"\":110000,\"res\":\"123\"}";
            updateDeviceVO.setStatus(1);
        }else {
            msg = "{\"A"+no+"\":100000,\"res\":\"1223\"}";
            updateDeviceVO.setStatus(0);
        }

        deviceService.updateDevice(updateDeviceVO);

        String sup =  hardwareService.getSubHardware(openDeviceVo.getHardwareId());


        if (sup!=null){

            mqttService.publish(msg,sup);

        }



       // mqttMessageSender.send("/corx/sub/CORX00001000",msg);


    }



    @Override
    public IPage<DeviceBO> getDevicePage(GetDeviceVo getDeviceVo) {
        QueryWrapper<Device> query = new QueryWrapper<>();

        if (getDeviceVo.getShopId()!=null){
            query.eq("shop_id",getDeviceVo.getShopId());
        }

        //新建分页条件
        Page<Device> p = new Page<>(getDeviceVo.getCurrentPage(),getDeviceVo.getPageSize());
        IPage<Device> userIPage = deviceMapper.selectPage(p,query);
        IPage<DeviceBO> page = new Page<>();
        List<DeviceBO> adminDetailBOList = new ArrayList<>();
        for (Device admin: userIPage.getRecords()){
            DeviceBO adminDetailBO = new DeviceBO();
            BeanUtils.copyProperties(admin,adminDetailBO);
            adminDetailBOList.add(adminDetailBO);
        }
        /* 将转化的BO放到的Records里面  */
        page.setRecords(adminDetailBOList);
        page.setCurrent(userIPage.getCurrent());
        page.setPages(userIPage.getPages());
        page.setPages(userIPage.getSize());
        page.setTotal(userIPage.getTotal());

        return page;
    }

    @Override
    public Boolean updateDevice(UpdateDeviceVO updateDeviceVO) {

        System.out.println("updateDeviceVO");
        System.out.println(updateDeviceVO);
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_id",updateDeviceVO.getDeviceId());
        Device device = deviceMapper.selectOne(queryWrapper);
        device.setStatus(updateDeviceVO.getStatus());

        if (updateDeviceVO.getShopId()!=null){
            device.setShopId(updateDeviceVO.getShopId());
        }
        if (updateDeviceVO.getStartTime()!=null){
            device.setStartTime(updateDeviceVO.getStartTime());
        }
        if (updateDeviceVO.getEndTime()!=null){
            device.setEndTime(updateDeviceVO.getEndTime());
        }

        if (updateDeviceVO.getBeforeStatus()!=null){
            device.setBeforeStatus(updateDeviceVO.getBeforeStatus());
        }
        if (updateDeviceVO.getAfterStatus()!=null){
            device.setAfterStatus(updateDeviceVO.getAfterStatus());
        }

        if (updateDeviceVO.getDeviceName()!=null){
            device.setDeviceName(updateDeviceVO.getDeviceName());
        }

        if (updateDeviceVO.getHardwareId()!=null){
            device.setHardwareId(updateDeviceVO.getHardwareId());
        }

        if (updateDeviceVO.getControl()!=null){
            device.setControl(updateDeviceVO.getControl());
        }


        return deviceMapper.update(device, queryWrapper) == 1;
    }

    @Override
    public Boolean addDevice(AddDeviceVo addDeviceVo) {
        Device device = new Device();
        BeanUtils.copyProperties(addDeviceVo,device);
        return deviceMapper.insert(device) == 1;
    }

    @Override
    public Boolean deleteDevice(Integer deviceId) {

        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_id",deviceId);
        return deviceMapper.delete(queryWrapper) == 1;
    }
}
